/*
 * @Author: intellectual-seeker 3336339701@qq.com
 * @Date: 2025-09-15 21:10:45
 * @LastEditors: intellectual-seeker 3336339701@qq.com
 * @LastEditTime: 2025-09-18 22:01:47
 * @FilePath: /code/lesson33/ThreadPool/Log.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#ifndef LOG_HPP
#define LOG_HPP
#include <ctime>
#include <sys/time.h>
#include <iostream>
using namespace std;
#include <cstdarg>
#include <unistd.h>
#include "LockGuard.hpp"
#include <fstream>

const char* logname = "log.txt";
bool gIsSave = false;

// 日志等级
enum level
{
    INFO = 0, // 信息
    DEBUG,    // 调试
    WARNING,  // 警告
    ERROR,    // 错误
    FATAL,    // 致命
    UNKNOWN   // 未知
};

//枚举类型转字符串
string LevelToString(int level)
{
    switch (level)
    {
    case INFO:
        return "Info";
    case DEBUG:
        return "Debug";
    case WARNING:
        return "Warning";
    case ERROR:
        return "Error";
    case FATAL:
        return "Fatal";
    case UNKNOWN:
        return "Unknown";
    }

    return "RUNNING_ERROR";
}

//获取当前时间并转换为字符串
string GetTimeString(time_t tm)
{
    struct tm* ptm = localtime(&tm);
    char timestring[1024];
    snprintf(timestring, sizeof(timestring),"%d-%d-%d %d:%d:%d",
    ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
    ptm->tm_hour, ptm->tm_min, ptm->tm_sec);

    return timestring;
}

void LogSaveFile(const char* logname, const string& message)
{
    ofstream ofs(logname, ios_base::out | ios_base::app);
    if(!ofs.is_open())//检测文件是否打开成功
    {
        return;
    }

    ofs << message;

    ofs.close();
}

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void logmessage(int level, time_t time, string file, int line, const char* arg, ...)
{
    char strarg[1024];
    va_list format;
    va_start(format, arg);
    vsnprintf(strarg, sizeof(strarg), arg, format);
    va_end(format);

    //加锁，防止日志信息打印混乱
    LockGuard lockguard(mutex);
    //函数传参换行不需要加 转义字符'\'
    string message = "[" + GetTimeString(time) + "]" + "[" + LevelToString(level) + "]"
    + "[" + to_string(getpid()) + "]"//新增进程pid
    + "[" + file + "]" + "[" + to_string(line) + "]"
    + strarg + "\n";

    if(gIsSave)
    {
        LogSaveFile(logname, message);
    }
    else
    {
        cout << message;
    }
}

//##__VA_ARGS__ 支持可变参数为0个，__VA_ARGS__不支持
//宏换行必须要加转义字符，将'\n'无效化
#define LOG(level, arg, ...)    \
do                              \
{                               \
    logmessage(level, time(nullptr), __FILE__, __LINE__, arg, ##__VA_ARGS__);   \
}while(0)

#define EnableFile()    \
do                      \
{                       \
    gIsSave = true;     \
} while (0)

#define EnableScreen()  \
do                      \
{                       \
    gIsSave = false;    \
} while (0)


#endif